﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSharp.Libs.WPF;
using System.IO;
using System.Text.RegularExpressions;



namespace PropertyGenerator
{
    class MainWindowViewModel : ViewModelBase
    {
        #region declarations
        private String _strInput = "Name,String,false\r\nVorname,String,false\r\nNameVorname,String,true\r\n";
        private String _strOutput = "";

        private Boolean _fCreateOnPropertyChanged = false;
        private Boolean _fCreateKeyConstants = false;

        private const string ALL_CAPS_PATTERN = "[a-z]";
        static readonly Regex All_Caps_Regex = new Regex(ALL_CAPS_PATTERN);
        #endregion


 
        #region constructor / terminator
        public MainWindowViewModel()
        {
            _EvaluateInput();
        }
        #endregion



        #region private functions
        private void _EvaluateInput()
        {
            try
            {
                String _strDeclarations = "";
                String _strProperties = "";
                String _strKeyConstants = "";
                _strOutput = "";

                using (StringReader SR = new StringReader(_strInput))
                {
                    String strLine = "";

                    while (true)
                    {
                        strLine = SR.ReadLine();

                        if (strLine == "" ||
                            strLine == null)
                        {
                            break;
                        }

                        String[] strValues = strLine.Split(',');

                        if (strValues.Count() >= 3 &&
                            strValues[0].Trim() != "" &&
                            strValues[1].Trim() != "")
                        {
                            Boolean fReadOnly = false;
                            Boolean.TryParse(strValues[2].Trim(), out fReadOnly);
                            String _strScope = "private ";
                            String _strVariableType = "";
                            String _strVariableName = "";
                            String _strPropertyName = "";
                            String _strVariableInitValue = "";

                            switch (strValues[1].Trim().ToLower())
                            {
                                case "string":
                                    _strVariableType = "String";
                                    _strVariableName = String.Concat("_str", strValues[0].Trim());
                                    _strPropertyName = strValues[0].Trim();
                                    _strVariableInitValue = "\"\"";
                                    break;

                                case "boolean":
                                case "bool":
                                    _strVariableType = "Boolean";
                                    _strVariableName = String.Concat("_f", strValues[0].Trim());
                                    _strPropertyName = strValues[0].Trim();
                                    _strVariableInitValue = "false";
                                    break;

                                case "int":
                                    _strVariableType = "int";
                                    _strVariableName = String.Concat("_int", strValues[0].Trim());
                                    _strPropertyName = strValues[0].Trim();
                                    _strVariableInitValue = "0";
                                    break;

                                case "int32":
                                    _strVariableType = "Int32";
                                    _strVariableName = String.Concat("_int", strValues[0].Trim());
                                    _strPropertyName = strValues[0].Trim();
                                    _strVariableInitValue = "0";
                                    break;

                                case "int64":
                                    _strVariableType = "Int64";
                                    _strVariableName = String.Concat("_int", strValues[0].Trim());
                                    _strPropertyName = strValues[0].Trim();
                                    _strVariableInitValue = "0";
                                    break;
                                
                                case "double":
                                    _strVariableType = "Double";
                                    _strVariableName = String.Concat("_dbl", strValues[0].Trim());
                                    _strPropertyName = strValues[0].Trim();
                                    _strVariableInitValue = "0";
                                    break;
                            }

                            _strDeclarations = String.Concat(_strDeclarations, _strScope, _strVariableType, " ", _strVariableName, " = ", _strVariableInitValue, ";\r\n");

                            _strProperties = String.Concat(_strProperties, "public ", _strVariableType, " ", _strPropertyName, "{get{return ", _strVariableName, ";}");
                            if (!fReadOnly)
                            {
                                if (_fCreateOnPropertyChanged)
                                {
                                    _strProperties = String.Concat(_strProperties, "set{", _strVariableName, " = value;OnPropertyChanged(\"", _strPropertyName, "\");}");
                                }
                                else
                                {
                                    _strProperties = String.Concat(_strProperties, "set{", _strVariableName, " = value;}");
                                }
                            }
                            _strProperties = String.Concat(_strProperties, "}\r\n\r\n");

                            if (_fCreateKeyConstants)
                            {
                                _strKeyConstants = String.Concat(_strKeyConstants, "\r\n", CreateKeyConstantLine(_strPropertyName));
                            }
                        }
                    }

                    if (_fCreateKeyConstants)
                    {
                        _strOutput = String.Concat(_strDeclarations, "\r\n", _strProperties, "\r\n\r\n\r\n", _strKeyConstants);
                    }
                    else
                    {
                        _strOutput = String.Concat(_strDeclarations, "\r\n", _strProperties);
                    }

                    
                    OnPropertyChanged("Output");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private String CreateKeyConstantLine(
            String PropertyName)
        {
            try
            {
                Int32 IDX = 0;
                String strResult = "public const String KEY_";

                while (IDX < PropertyName.Length)
                {
                    String testChar = PropertyName.Substring(IDX, 1);

                    if (!AllUpperCase(testChar) ||
                        IDX == 0)
                    {
                        strResult = String.Concat(strResult, testChar.ToUpper());
                    }
                    else
                    {
                        strResult = String.Concat(strResult, "_", testChar.ToUpper());
                    }

                    IDX++;
                }

                return String.Concat(strResult, " = \"", PropertyName, "\";");
            }
            catch (Exception ex)
            {
                return "";
            }
        }

        private Boolean AllUpperCase(
            String inputString)
        {
            try
            {
                if (All_Caps_Regex.IsMatch(inputString))
                {
                    return false;
                }

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        #endregion



        #region interface
        #region properties
        public Boolean CreateOnPropertyChanged
        {
            get
            {
                return _fCreateOnPropertyChanged;
            }
            set
            {
                _fCreateOnPropertyChanged = value;
                _EvaluateInput();
            }
        }

        public Boolean CreateKeyConstants
        {
            get
            {
                return _fCreateKeyConstants;
            }
            set
            {
                _fCreateKeyConstants = value;
                _EvaluateInput();
            }
        }

        public String Input
        {
            get
            {
                return _strInput;
            }
            set
            {
                _strInput = value;
                _EvaluateInput();
            }
        }

        public String Output
        {
            get
            {
                return _strOutput;
            }
        }
        #endregion

        #region methods
        #endregion
        #endregion




    }
}
/* Tests für die Funktion können hier hin und per Copy&Paste ins Inputfenster geschmissen werden
 * 
 * Alle derzeitig unterstützten Variablentypen:
Text,String,false
Schalter,Boolean,false
NormalerInteger,int,false
Integer32Bit,int32,false
Integer64Bit,int64,false
 * 
 * 
 * Spezialtests mit Leerzeichen usw.
    Text, String,false
    Schalter , Boolean,false
    NormalerInteger ,int , false
    Integer32Bit,int32,false  
    Integer64Bit , int64 , false 
 *  
 */